package com.uplooking.service.impl;

import java.awt.Menu;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;
import javax.transaction.Transactional;
import javax.transaction.Transactional.TxType;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.cache.CacheProperties.Redis;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSONObject;
import com.uplooking.constant.CommConstants;
import com.uplooking.constant.CustConstants;
import com.uplooking.constant.RedisConstants;
import com.uplooking.constant.RoleConstants;
import com.uplooking.constant.UserConstants;
import com.uplooking.dao.CustDO;
import com.uplooking.dao.UserDO;
import com.uplooking.pojo.CustVO;
import com.uplooking.pojo.DictVO;
import com.uplooking.pojo.MenuVO;
import com.uplooking.pojo.ShopVO;
import com.uplooking.pojo.TreeVO;
import com.uplooking.pojo.UserVO;
import com.uplooking.service.UserService;
import com.uplooking.util.FileUtils;

@Service("userService")
public class UserServiceImpl implements UserService, UserDetailsService {

	private final String pathname = "src\\main\\resources\\static\\html\\images\\user.jpg";
	
	@Autowired
	private UserDO userDO;
	
	@Autowired
	private CustDO custDO;
	
	@Autowired
	PasswordEncoder passwordEncoder;
	
	@Autowired
	StringRedisTemplate redis;
	
	@Autowired
	HttpSession session;

	@Override
	@Transactional(value=TxType.SUPPORTS)
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		UserVO userVO = userDO.findById(username).orElse(null);
		return userVO;
	}

	@Override
	@Transactional(value=TxType.REQUIRED)
	public Map<String, Object> registCust(String username, String password) throws Exception {
		UserVO userVO = new UserVO(username, passwordEncoder.encode(password), 
				UserConstants.RegistCustStatus, RoleConstants.RoleCust);
		CustVO custVO = new CustVO(username,"","","");
		userVO.setCustVO(custVO);
		userDO.save(userVO);
		redis.opsForHash().put(RedisConstants.PrefixImages, 
				RedisConstants.PrefixImagesPhoto+username, 
				FileUtils.encode(pathname));
		return UserConstants.CustRegistSuccess();
	}

	@Override
	@Transactional(value=TxType.REQUIRED)
	public Map<String, Object> registShop(String username, String password, ShopVO shopVO, MultipartFile logo,
			MultipartFile person, MultipartFile license) throws Exception {
		UserVO userVO = new UserVO(username, passwordEncoder.encode(password), 
				UserConstants.RegistShopStatus, RoleConstants.RoleShop);
		shopVO.setUser(username);
		userVO.setShopVO(shopVO);
		userDO.save(userVO);
		//logo
		redis.opsForHash().put(RedisConstants.PrefixImages, 
				RedisConstants.PrefixImagesLogo+username, 
				Base64Utils.encodeToString(logo.getBytes()));
		//person
		redis.opsForHash().put(RedisConstants.PrefixImages, 
				RedisConstants.PrefixImagesPerson+username, 
				Base64Utils.encodeToString(person.getBytes()));
		//license
		redis.opsForHash().put(RedisConstants.PrefixImages, 
				RedisConstants.PrefixImagesLicense+username, 
				Base64Utils.encodeToString(license.getBytes()));
		return UserConstants.ShopRegistSuccess();
	}

	@Override
	public List<DictVO> getShopValues() {
		String text = redis.opsForHash().get(RedisConstants.PrefixDict, 
				RedisConstants.PrefixDictList+UserConstants.DictShopValues).toString();
		return JSONObject.parseArray(text, DictVO.class);
	}

	@Override
	@Transactional(value=TxType.REQUIRED)
	public Map<String, Object> registAdmin() throws Exception {
		String username ="admin";
		CharSequence password ="a123123";
		UserVO userVO = new UserVO(username, passwordEncoder.encode(password), 
				UserConstants.RegistCustStatus, RoleConstants.RoleAdmin);
		CustVO custVO = new CustVO(username,"","","");
		userVO.setCustVO(custVO);
		userDO.save(userVO);
		redis.opsForHash().put(RedisConstants.PrefixImages, 
				RedisConstants.PrefixImagesPhoto+username, 
				FileUtils.encode(pathname));
		return UserConstants.AdminRegistSuccess();
	}

	@Override
	public List<TreeVO> getMenuTree() {
		UserVO userVO = (UserVO) session.getAttribute(CommConstants.CommUser);
		List<MenuVO> list = userVO.getRoleVO().getMenuVOs();
		List<TreeVO> nodes = new ArrayList<TreeVO>();
		for(MenuVO menuVO:list) {
			TreeVO node = new TreeVO(menuVO.getMtitle(),
					menuVO.getMicon(),menuVO.getMroute(),menuVO.getMtip());
			nodes.add(node);
		}
		return nodes;
	}

	@Override
	public List<DictVO> getCustGenders() {
		String text = redis.opsForHash().get(RedisConstants.PrefixDict, 
				RedisConstants.PrefixDictList+UserConstants.DictCustGenders).toString();
		return JSONObject.parseArray(text, DictVO.class);
	}

	@Override
	@Transactional(value=TxType.REQUIRED)
	public Map<String, Object> updateCust(CustVO custVO) throws Exception {
		custDO.save(custVO);
		return CustConstants.UpdateCustSuccess();
	}

}
